﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Inaction.Rule
{
    [Serializable]
    public class EnumDescriptionList : List<EnumDescription>
    {
        static Dictionary<Type, EnumDescriptionList> enums = new Dictionary<Type, EnumDescriptionList>();
        public static EnumDescriptionList Query(Type enumType)
        {
            if (enumType == null || !enumType.IsEnum)
            {
                throw new Exception(Inaction.Resource.Properties.Resources.NotIsEnumType);
            }
            if (enums.ContainsKey(enumType)) return enums[enumType];
            var list = new EnumDescriptionList();
            var fileds = enumType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            foreach (var field in fileds)
            {
                if (!field.IsLiteral || !field.FieldType.IsEnum) continue;
                var description = field.GetCustomAttribute<DescriptionAttribute>();
                if (description == null)
                {
                    description = new DescriptionAttribute(field.Name);
                }
                list.Add(
                    new EnumDescription()
                    {
                        Description = description.Description,
                        Value = (Enum)field.GetValue(null),
                    });
            }
            enums.Add(enumType, list);
            return list;
        }

        public static EnumDescriptionList Query<T>(params T[] values)
        {
            var enumType = typeof(T);
            if (values.Count() == 0) return Query(enumType);
            if (!enumType.IsEnum)
            {
                throw new Exception(Inaction.Resource.Properties.Resources.NotIsEnumType);
            }
            var list = new EnumDescriptionList();
            var fileds = enumType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            foreach (var field in fileds)
            {
                if (!field.IsLiteral || !field.FieldType.IsEnum) continue;
                var value = field.GetValue(null);
                if (!values.Contains((T)value)) continue;
                var description = field.GetCustomAttribute<DescriptionAttribute>();
                if (description == null)
                {
                    description = new DescriptionAttribute(field.Name);
                }
                list.Add(
                    new EnumDescription()
                    {
                        Description = description.Description,
                        Value = (Enum)value,

                    });
            }
            return list;
        }

        public static T[] ConvertToArray<T>(string strValues)
        {
            if (string.IsNullOrEmpty(strValues)) return null;
            var list = Query<T>();
            var enums = new List<T>();
            var str = strValues.Split(',');
            foreach (var i in str)
            {
                var s = i.Trim();
                var item = list.FirstOrDefault(p => p.Value.ToString() == s || p.Key.ToString() == s);
                if (item != null)
                {
                    enums.Add((T)item.Value);
                }
            }
            return enums.ToArray();
        }
        public static string ConvertToString<T>(IEnumerable<T> enumValues)
        {
            if (enumValues == null || enumValues.Count() == 0) return string.Empty;
            var str = string.Empty;
            foreach (var e in enumValues)
            {
                if (!string.IsNullOrEmpty(str))
                {
                    str += ",";
                }
                str += Enum.GetName(typeof(T), e);
            }
            return str;
        }
    }
}
